package com.xkstream.client.ui.live.fragment;

import android.app.Dialog;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.UiThread;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.google.gson.Gson;
import com.xkstream.client.R;
import com.xkstream.client.api.API;
import com.xkstream.client.application.Application;
import com.xkstream.client.base.BaseData;
import com.xkstream.client.base.BaseFragment;
import com.xkstream.client.common.CommonDialog;
import com.xkstream.client.entity.Gift;
import com.xkstream.client.entity.User;
import com.xkstream.client.entity.kt.GiftStarData;
import com.xkstream.client.lgim.LgExtension;
import com.xkstream.client.lgim.LgMessage;
import com.xkstream.client.lgim.LgMessageParser;
import com.xkstream.client.presenter.kt.ChatroomContract;
import com.xkstream.client.presenter.kt.ChatroomPresenter;
import com.xkstream.client.rx.Rxbus;
import com.xkstream.client.ui.adapter.ChatRoomAdapter_Lg;
import com.xkstream.client.ui.adapter.ChatRoomAdapter_V2;
import com.xkstream.client.ui.live.LiveRoomActivity_V2;
import com.xkstream.client.ui.live.LiveWebSocket;
import com.xkstream.client.utils.AsyncImage;
import com.xkstream.client.utils.DeviceUtils;
import com.xkstream.client.utils.L;
import com.xkstream.client.utils.LogFileUtil;
import com.xkstream.client.utils.LogUtil;
import com.xkstream.client.view.CircleImageView;
import com.xkstream.client.view.gift.GiftShowManager;
import com.xkstream.client.view.gift.GiftShowManager_Lg;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import butterknife.BindString;
import butterknife.BindView;
import butterknife.OnClick;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;

/**
 * Created by xiaoyi on 2017-10-11.
 */

public class ChatroomFragment_lg extends BaseFragment<ChatroomContract.Presenter> implements
        ChatroomContract.View {
    @BindView(R.id.tv_bulletin)
    TextView tvBulletin;
    @BindView(R.id.recycler_chat)
    RecyclerView recyclerChat;
    @BindView(R.id.llGift)
    LinearLayout llGift;
    @BindView(R.id.root)
    LinearLayout rootLayout;
    @BindView(R.id.layout_gift_star)
    View layoutGiftStart;
    @BindView(R.id.layout_bell_star)
    View layoutBellStart;

    @BindView(R.id.bellStar)
    TextView tvBellStar;
    @BindView(R.id.giftStar)
    TextView tvGiftStar;

    @BindView(R.id.llBellStar)
    LinearLayout llBellStar;

    @BindString(R.string.bell_many)
    String strWin;

    private boolean isPause = false;

    List<Object> mMessages = new ArrayList<>();

    LinearLayoutManager layoutManager;
    @BindView(R.id.tvName1)
    TextView tvName1;
    @BindView(R.id.tvName2)
    TextView tvName2;
    @BindView(R.id.tvName3)
    TextView tvName3;
    @BindView(R.id.tvName4)
    TextView tvName4;
    @BindView(R.id.tvName5)
    TextView tvName5;
    @BindView(R.id.tvName6)
    TextView tvName6;
    @BindView(R.id.tvName7)
    TextView tvName7;
    @BindView(R.id.tvName8)
    TextView tvName8;
    @BindView(R.id.tvName9)
    TextView tvName9;
    private String chatroomId;
    private int gameType;

    @BindView(R.id.rlStarDes)
    RelativeLayout rlStarDes;
    @BindView(R.id.tvStarDes)
    TextView tvStarDes;

    @BindView(R.id.ivHeader)
    CircleImageView ivHeader;
    @BindView(R.id.tvNickname)
    TextView tvNickName;
    @BindView(R.id.tvViewCount)
    TextView tvViewCount;


    @BindString(R.string.viewer_count)
    String strViewCount;


    private GiftShowManager_Lg giftShowManager;

    private static final int CODE_GIFTSTAR = 0X1001;
    private static final int CODE_RECONNECT = 0X2001;

    private static int connectCount = 0;

    private List<GiftStarData.GiftStar> giftStarList;

    private MHandler mHandler;
    ChatRoomAdapter_Lg chatAdapter;


    /**
     * websocket
     */
    private LiveWebSocket webSocket;
    private OkHttpClient client;
    private Request request;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_chatroom;
    }

    @Override
    public void initViews(View root) {
        chatroomId = getArguments().getString("chatroomId");
        gameType = getArguments().getInt("gameType");
        initAnchor();
        presenter = new ChatroomPresenter(this);
        layoutManager = new LinearLayoutManager(mActivity, LinearLayoutManager.VERTICAL, false);
        recyclerChat.setLayoutManager(layoutManager);

        chatAdapter = new ChatRoomAdapter_Lg(mActivity, mMessages);
        recyclerChat.setAdapter(chatAdapter);


        giftShowManager = new GiftShowManager_Lg(mActivity, llGift);
        giftShowManager.showGift();

        recyclerChat.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_UP
                    && event.getX() > (DeviceUtils.deviceWidth(mActivity) / 2)
                    ) {
                hideStarLayout();
            }
            return false;
        });
        registerRxBus();
        mHandler = new MHandler(this);
        mHandler.sendEmptyMessageDelayed(CODE_GIFTSTAR, 1000);
        connectWebSocket();
    }

    private void initAnchor() {
        tvViewCount.setText(String.format(strViewCount, 0));
        AsyncImage.loadPhoto(mActivity, getArguments().getString("head"), ivHeader);
        tvNickName.setText(getArguments().getString("nickname"));
    }

    private void registerRxBus() {
        Rxbus.getDefault().register(String.class)
                .subscribe((s) -> {
                    if (s.equals("onclick")) {
                        hideStarLayout();
                    }
                });
    }

    private void hideStarLayout() {
        if (layoutGiftStart == null) return;
        if (layoutGiftStart.getVisibility() == View.VISIBLE) {
            layoutGiftStart.setVisibility(View.GONE);
        }
        if (layoutBellStart.getVisibility() == View.VISIBLE) {
            layoutBellStart.setVisibility(View.GONE);
        }
        if (rlStarDes.getVisibility() == View.VISIBLE) {
            rlStarDes.setVisibility(View.GONE);
        }
        tvGiftStar.setVisibility(View.VISIBLE);
        tvBellStar.setVisibility(View.VISIBLE);

    }


    @OnClick({R.id.bellStar, R.id.giftStar,
            R.id.recycler_chat, R.id.llGift, R.id.v_cover,
            R.id.iv_bell_help, R.id.iv_help_gift})
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bellStar:
                layoutBellStart.setVisibility(View.VISIBLE);
                tvBellStar.setVisibility(View.GONE);
                tvGiftStar.setVisibility(View.GONE);
//                playAnim(v);
                break;
            case R.id.giftStar:
                layoutGiftStart.setVisibility(View.VISIBLE);
                tvBellStar.setVisibility(View.GONE);
                tvGiftStar.setVisibility(View.GONE);
//                playAnim(v);
                break;

            case R.id.llGift:
            case R.id.v_cover:
            case R.id.recycler_chat:
                hideStarLayout();
                break;
            case R.id.iv_bell_help:
                setStarDes(false);
                break;

            case R.id.iv_help_gift:
                setStarDes(true);
                break;


        }
    }

    @UiThread
    private void addBellItem(LgMessage message) {
        if (llBellStar.getChildAt(0) instanceof TextView) {
            llBellStar.removeAllViews();
        }
        int count = llBellStar.getChildCount();
        LgExtension extension = message.getData();
        if (count < 3) {
            View item = View.inflate(getContext(), R.layout.layout_bell_star_item, null);
            TextView tvName = (TextView) item.findViewById(R.id.tvName);
            TextView tvCount = (TextView) item.findViewById(R.id.tvCount);
            tvCount.setText(String.format(strWin));
            tvName.setText(extension.getUserNickName());
            if (index > count) {
                index = count;
            }
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.setMargins(0, DeviceUtils.dp2px(getContext(), 5),
                    0, DeviceUtils.dp2px(getContext(), 5));
            llBellStar.addView(item, index, params);
        } else if (index == 3) {
            View item = llBellStar.getChildAt(index);
            if (item == null) return;
            TextView tvName = (TextView) item.findViewById(R.id.tvName);
            TextView tvCount = (TextView) item.findViewById(R.id.tvCount);
            tvCount.setText(String.format(strWin));
            tvName.setText(extension.getUserNickName());
        }
    }

    private void setGiftStarItem(int index, String name) {
        String tag = "tvName" + (index + 1);
        TextView view = (TextView) root.findViewWithTag(tag);
        if (view != null) {
            view.setText(name);
        }
    }

    private void setStarDes(boolean isGift) {
        rlStarDes.setVisibility(View.VISIBLE);
        if (isGift) {
            tvStarDes.setText(Html.fromHtml(getResources().getString(R.string.gift_star_des)));
        } else {
            tvStarDes.setText(Html.fromHtml(getResources().getString(R.string.bell_star_des)));
        }
    }

    private void playAnim(View view) {
        if (view.getVisibility() == View.GONE) return;
        Animation anim = new TranslateAnimation(0, 0, 0, view.getWidth() * 0.1f);
        CycleInterpolator interpolator = new CycleInterpolator(2);
        anim.setDuration(1000);
        anim.setInterpolator(interpolator);
        view.startAnimation(anim);
    }


    private void setAdmin(String userId) {
        User user = Application.getUser();
        Map<String, Object> params = new HashMap<>();
        params.put("operator", user.getUser_code());
        params.put("roomid", chatroomId);
        params.put("user_code", userId);
        ((LiveRoomActivity_V2) getActivity()).setAdmin(params);
    }

    private void shutUp(String userId) {
        User user = Application.getUser();
        Map<String, Object> params = new HashMap<>();
        params.put("operator", user.getUser_code());
        params.put("roomid", chatroomId);
        params.put("target", userId);
        params.put("muteDuration", 86400 + "");
        ((LiveRoomActivity_V2) getActivity()).chatroomMute(params);
    }

    private Bitmap getHead(String id) {
        AssetManager manager = getActivity().getAssets();
        InputStream ios = null;
        try {
            ios = manager.open("head/" + id + ".jpg");
            return BitmapFactory.decodeStream(ios);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ios != null) {
                    ios.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void showRankGiftStar(@NotNull BaseData<GiftStarData> data) {
        GiftStarData giftStarData = data.getData();
        if (giftStarData != null && giftStarData.getRankList() != null &&
                giftStarData.getRankList().size() > 0) {
            List<GiftStarData.GiftStar> starList = giftStarData.getRankList();
            sortGiftStarList(starList);
        }
    }

    int index = 0;

    private void sortGiftStarList(List<GiftStarData.GiftStar> list) {
        index++;
        if (index % 4 == 0) {
            // test(list);
        }
        LogUtil.e(TAG, list.toString());
        if (giftStarList == null) {
            giftStarList = list;
            for (int i = 0; i < giftStarList.size(); i++) {
                setGiftStarItem(i, giftStarList.get(i).getNickname());
            }
            playAnim(tvGiftStar);
        } else {
            List<GiftStarData.GiftStar> tmp = giftStarList;

            if (!tmp.equals(list)) {
                giftStarList = list;
                for (int i = 0; i < giftStarList.size(); i++) {
                    setGiftStarItem(i, giftStarList.get(i).getNickname());
                }
                playAnim(tvGiftStar);
            }
        }

    }

    @Override
    public void setPresenter(ChatroomContract.Presenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    private static class MHandler extends Handler {
        WeakReference<ChatroomFragment_lg> reference;

        public MHandler(ChatroomFragment_lg fragment) {
            this.reference = new WeakReference<ChatroomFragment_lg>(fragment);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CODE_GIFTSTAR:
                    removeMessages(CODE_GIFTSTAR);
                    if (reference.get() != null) {
                        reference.get().getRankGiftStar();
                        sendEmptyMessageDelayed(CODE_GIFTSTAR, 5000);
                    }
                    break;
                case CODE_RECONNECT:
                    if (reference.get() != null) {
                        if (connectCount >= 5) {
                            reference.get().connectFailed();
                        } else {
                            reference.get().connectWebSocket();
                            connectCount++;
                        }

                    }
                    break;
            }
        }
    }

    private void getRankGiftStar() {
        Map<String, String> params = new HashMap<>();
        String userCode = Application.getUser().getUser_code();
        params.put("anchor_user_code", userCode);
        presenter.getRankGiftStar(params);
    }

    @UiThread
    private void connectFailed() {
        connectCount = 0;
        showExitDialog("后台断开连接");
        mActivity.finish();
    }

    private void showExitDialog(String title) {
        CommonDialog dialog = new CommonDialog(mActivity);
        dialog.setListener(() -> {
            mActivity.finish();
            release();
            ((LiveRoomActivity_V2) mActivity).anchorOff(1);
        });
        dialog.setTitle(title);
        dialog.setSingleButton();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mHandler.removeCallbacksAndMessages(null);
        webSocket.closeWebSocket();
        connectCount = 0;
    }


    private void connectWebSocket() {
        if (webSocket != null) {
            release();
        }
        L.e(TAG, " onConnect connectWebSocket");
        User user = Application.getUser();
        StringBuilder url = new StringBuilder(API.WS_HOST)
                .append(API.LONG_URL)
                .append("userCode=")
                .append(user.getUser_code())
                .append("&anchor_user_code=")
                .append(user.getUser_code())
                .append("&game_type=")
                .append(gameType)
                .append("&device=2")
                .append("&isAnchor=1")
                /*.append("&token=" + user.getToken())*/;
        L.e(TAG, " websocket url " + url.toString());
        webSocket = LiveWebSocket.getDefault(new LiveWebSocket.Callback() {
            @Override
            public void onOpen(WebSocket socket, Response response) {
                L.e(TAG, " onConnect onOpen");
                mMessages.add("直播开启，根据相关法律法规，请勿传播色情，反动等非法内容");
                LogFileUtil.getDefault().put(TAG, String.format("socket connect open  "));
                webSocket.sendMessage(LgMessageParser.generateEnterMessage());
                if (!isPause) {
                    ((LiveRoomActivity_V2) mActivity).anchorOff(1);
                }
            }

            @Override
            public void onReceive(LgMessage message) {
                if (message.getCmmid() == LgMessageParser.CODE_NORMAL
                        || message.getCmmid() == LgMessageParser.CODE_ENTER
                        ) {
                    mMessages.add(message);
                    mActivity.runOnUiThread(() -> {
                        if (recyclerChat == null) return;
                        chatAdapter.notifyDataSetChanged();
                        recyclerChat.scrollToPosition(chatAdapter.getItemCount() - 1);
                    });
                } else if (message.getCmmid() == LgMessageParser.CODE_ONLINENUM) {
                    mActivity.runOnUiThread(() -> {
                        if (tvViewCount != null)
                            tvViewCount.setText("" + message.getData().getOnline());
                    });
                } else if (message.getCmmid() == LgMessageParser.CODE_GIFT) {
                    LgExtension extension = message.getData();
                    if (extension.getAnchorInfo().getAnchorCode()
                            .equals(Application.getUser().getUser_code())){
                        mMessages.add(message);
                        mActivity.runOnUiThread(() -> {
                            if (recyclerChat == null) return;
                            chatAdapter.notifyDataSetChanged();
                            LgExtension.GiftInfo gift = message.getData().getGiftInfo();
                            LgExtension.ExtInfo extInfo = message.getData().getExtInfo();
                            gift.setSenderCode(extInfo.getMsgSender());
                            gift.setSenderName(extInfo.getNickname());
                            giftShowManager.addGift(gift);
                            recyclerChat.scrollToPosition(chatAdapter.getItemCount() - 1);
                        });
                    }

                } else if (message.getCmmid() == LgMessageParser.CODE_WIN) {
                    mActivity.runOnUiThread(() -> {
                        if (tvBellStar == null) return;
                        playAnim(tvBellStar);
                        addBellItem(message);
                    });
                } else if (message.getCmmid() == LgMessageParser.CODE_NOTIFICATION) {
                    mActivity.runOnUiThread(() -> {
                        showNotification(message);
                    });
                }

            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                L.e(TAG, " onConnect onClosed");
                LogFileUtil.getDefault().put(TAG, String.format("socket onClosed  "));
            }

            @Override
            public void onFailure(WebSocket socket, Throwable t, Response response) {
                L.e(TAG, " onConnect onFailure");
                LogFileUtil.getDefault().put(TAG, String.format("socket connect onFailure  "));
                webSocket.closeWebSocket();
                if (connectCount < 5) {
                    mHandler.sendEmptyMessageDelayed(CODE_RECONNECT, 10000);
                }
            }
        });

        client = new OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build();
        request = new Request.Builder().url(url.toString()).get().build();
        client.newWebSocket(request, webSocket);
        client.dispatcher().executorService().shutdown();
    }

    private void showNotification(LgMessage message) {
        String content = message.getData().getMessage();
        if (TextUtils.isEmpty(content) || tvBulletin == null) return;
        tvBulletin.setText(content);
        tvBulletin.setVisibility(View.VISIBLE);
        tvBulletin.postDelayed(() -> {
            tvBulletin.setVisibility(View.GONE);
        }, 1000);
    }


    private void release() {
        LogUtil.e(TAG, "exectime release  " + System.currentTimeMillis());
        if (webSocket != null)
            webSocket.closeWebSocket();
        client = null;
        request = null;
    }

    @Override
    public void onResume() {
        super.onResume();
        isPause = false;
    }

    @Override
    public void onPause() {
        super.onPause();
        isPause = true;
    }
}